#!/usr/bin/env python
# encoding=utf-8

"""Simple TCP/IP proxy for libnotify.

This program lets you send pop-up notifications from remote servers to your
workstation.  You start this program then connect to a remote server using SSH,
having port 8111 forwarded back to you, then you send messages to that port.
See the README.markdown file for details.
"""

import os
if "DISPLAY" not in os.environ:
    os.environ["DISPLAY"] = "0:0"

import signal
import socket
import sys
import time

import pynotify


HOST = "localhost"
PORT = 8111


def serve():
    srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    srv.bind((HOST, PORT))
    srv.listen(5)

    last_ts = time.time()

    #print "Listening for messages on %s:%u" % (HOST, PORT)

    try:
        while True:
            (client, address) = srv.accept()
            print "Incoming connection from %s:%s" % address

            data = ""
            while True:
                tmp = client.recv(1024)
                if not tmp:
                    break
                data += tmp

            if data.strip() and (time.time() - last_ts > 15):
                process_message(data)
                last_ts = time.time()

            client.close()
    finally:
        srv.close()


def sigterm_handler(sig, frame):
    print "Caught SIGTERM."
    exit(1)


def process_message(text):
    lines = text.strip().decode("utf-8").split("\n")
    if len(lines) < 2:
        lines.insert(0, "message")
    if len(lines) < 3:
        lines.append("dialog-warning")

    pynotify.init("tcp-gate")
    pynotify.Notification(lines[0], lines[1], lines[2]).show()
    pynotify.uninit()


def serve_http():
    signal.signal(signal.SIGTERM, sigterm_handler)

    while True:
        delay = 1
        try:
            serve()
        except KeyboardInterrupt:
            print "Interrupted."
            exit(0)
        except socket.error, e:
            print "Socket error %u: %s" % (e.errno, e.strerror)
            if e.errno == 98:
                exit(1)
            delay = 15
        except Exception, e:
            print "ERROR %s: %s" % (type(e), e)

        print "Restarting in %u second(s)." % delay
        time.sleep(delay)


def serve_inetd():
    process_message(sys.stdin.read())


if __name__ == "__main__":
    command = sys.argv[1] if len(sys.argv) > 1 else None

    if command == "serve":
        serve_http()
    elif command == "inetd":
        serve_inetd()
    else:
        print "Usage: %s serve|inetd" % sys.argv[0]
        
